package org.example.core.mysql;

import org.example.core.mysql.enums.OperatorTypeEnum;
import org.example.core.mysql.enums.SqlOperatorEnum;

import java.util.LinkedList;
import java.util.List;

public class Where {
    private List<KeyAndValuePair> keyAndValuePairs = new LinkedList<>();

    public List<KeyAndValuePair> getKeyAndValuePairs() {
        return keyAndValuePairs;
    }

    private Where() {

    }

    public static Where build() {
        return new Where();
    }

    public Where field(String field) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.FILED_OPERATOR_VALUE.ordinal(), field));
        return this;
    }

    public Where and() {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.AND.toString()));
        return this;
    }

    public Where or() {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.OR.toString()));
        return this;
    }

    public Where leftBracket() {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.LEFT_BRACKET.toString()));
        return this;
    }

    public Where rightBracket() {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.RIGHT_BRACKET.toString()));
        return this;
    }

    public Where equal(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.EQUAL.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), value));
        return this;
    }

    public Where notEqual(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.NOT_EQUAL.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), value));
        return this;
    }

    public Where in(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.IN.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.MORE_VALUE.ordinal(), value));
        return this;
    }

    public Where like(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.LIKE.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), "%" + value + "%"));
        return this;
    }

    public Where lessThen(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.LESS_THEN.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), value));
        return this;
    }

    public Where lessEqualThen(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.LESS_EQUAL_THEN.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), value));
        return this;
    }

    public Where rightThen(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.RIGHT_THEN.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), value));
        return this;
    }

    public Where rightEqualThen(Object value) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.RIGHT_EQUAL_THEN.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), value));
        return this;
    }

    public Where betweenAnd(Object betweenValue, Object andValue) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.BETWEEN));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), betweenValue));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.OPERATOR_VALUE.ordinal(), SqlOperatorEnum.AND.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.ONE_VALUE.ordinal(), andValue));
        return this;
    }

    public Where limit(int page, int limit) {
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.LIMIT_TYPE.ordinal(), SqlOperatorEnum.LIMIT.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.LIMIT_TYPE.ordinal(), (page - 1) * limit));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.LIMIT_TYPE.ordinal(), SqlOperatorEnum.COMMA.toString()));
        keyAndValuePairs.add(KeyAndValuePair.build(OperatorTypeEnum.LIMIT_TYPE.ordinal(), limit));
        return this;
    }
}
